package com.antler.smt.admin.controller;

import com.antler.smt.admin.annotation.OperateCut;
import com.antler.smt.admin.utils.ShiroUtils;
import com.antler.smt.enums.ResultCodeEnum;
import com.antler.smt.request.admin.LoginReq;
import com.antler.smt.response.base.Result;
import com.antler.smt.service.admin.UserService;
import com.antler.smt.utils.LogUtil;
import com.antler.smt.utils.StringUtil;
import com.antler.smt.validate.DataValidator;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * 登录
 *
 * @author vic
 * @date 2018-03-28 22:44
 */
@RestController
@RequestMapping(value = "/permission")
@Api(description = "登录接口")
public class LoginController extends BaseController {

    /**
     * 日志
     */
    private static Logger log = LogUtil.get();

    /**
     * 图片生产者
     */
    @Autowired
    private Producer producer;

    /**
     * 用户接口
     */
    @Resource
    private UserService userService;

    /**
     * 生成验证码
     *
     * @param response 返回实体
     * @throws ServletException Servlet异常
     * @throws IOException      IO异常
     */
    @GetMapping("captcha.jpg")
    @ApiOperation(value = "生成验证码")
    public void captcha(HttpServletResponse response) throws ServletException, IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");

        //生成文字验证码
        String text = producer.createText();
        //生成图片验证码
        BufferedImage image = producer.createImage(text);
        //保存到shiro session
        ShiroUtils.setSessionAttribute(Constants.KAPTCHA_SESSION_KEY, text);

        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
    }

    /**
     * 登录接口
     *
     * @param request 请求实体
     * @return 返回实体
     */
    @PostMapping("/login")
    @ApiOperation(value = "登录", httpMethod = "POST")
    @OperateCut(content = "项目专员登陆")
    public Result login(@RequestBody LoginReq request) {
        Result result;
        DataValidator.isNull(request, "登录接口，请求参数不能为空！");
        DataValidator.isBlank(request.getJobNum(), "用户名必传！");
        DataValidator.isBlank(request.getPassword(), "密码必传！");
        /*DataValidator.isBlank(request.getCaptcha(), "验证码必传！");*/
        try {
            String captcha = ShiroUtils.getKaptcha(Constants.KAPTCHA_SESSION_KEY);
            if (StringUtil.isEmpty(captcha)) {
                return new Result(ResultCodeEnum.QUERY_DATA_ERROR, "获取验证码为空！");
            }
            if (!request.getCaptcha().equalsIgnoreCase(captcha)) {
                return new Result(ResultCodeEnum.QUERY_DATA_ERROR, "验证码不正确");
            }
            Subject subject = ShiroUtils.getSubject();
            //sha256加密
            String password = ShiroUtils.sha256(request.getPassword());
            UsernamePasswordToken token = new UsernamePasswordToken(request.getJobNum(), password);
            subject.login(token);
            //更新用户表最后登录时间
            Integer updateLastLoginTime = userService.updateLastLoginTime(getUserId());
            if (updateLastLoginTime <= 0) {
                return new Result(ResultCodeEnum.QUERY_DATA_ERROR, "更新最后登录时间失败！");
            }
            result = new Result();
        } catch (UnknownAccountException e) {
            log.error(e.getMessage(), e);
            result = new Result(ResultCodeEnum.QUERY_DATA_ERROR, e.getMessage());
        } catch (IncorrectCredentialsException e) {
            log.error("账号或密码不正确", e);
            result = new Result(ResultCodeEnum.QUERY_DATA_ERROR, "账号或密码不正确");
        } catch (LockedAccountException e) {
            log.error("账号已被锁定,请联系管理员", e);
            result = new Result(ResultCodeEnum.QUERY_DATA_ERROR, "账号已被锁定,请联系管理员");
        } catch (AuthenticationException e) {
            log.error("账户验证失败", e);
            result = new Result(ResultCodeEnum.QUERY_DATA_ERROR, "账户验证失败");
        }
        return result;
    }

    /**
     * 注销
     *
     * @return 返回实体
     */
    @GetMapping(value = "/logout")
    @OperateCut(content = "项目专员注销")
    @ApiOperation(value = "注销", httpMethod = "GET")
    public Result logout() {
        ShiroUtils.logout();
        return new Result();
    }
}
